package com.zenithmind.mall.controller;

import com.zenithmind.common.annotation.Log;
import com.zenithmind.common.annotation.RequireAuth;
import com.zenithmind.common.constant.OperationTypeEnum;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.result.Result;
import com.zenithmind.mall.pojo.dto.CouponDTO;
import com.zenithmind.mall.pojo.query.CouponQuery;
import com.zenithmind.mall.pojo.vo.CouponVO;
import com.zenithmind.mall.service.CouponManagementService;
import com.zenithmind.mall.service.CouponUserService;
import com.zenithmind.mall.service.CouponCalculationService;
import com.zenithmind.mall.service.CouponUsageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.List;

/**
 * 优惠券控制器 - 遵循控制器层最佳实践，只处理HTTP请求响应，业务逻辑委托给服务层
 *
 * @author ZenithMind Team
 * @since 2025-06-09
 */
@Slf4j
@RestController
@RequestMapping("/api/zenithMind/mall/coupon")
@RequiredArgsConstructor
@Tag(name = "优惠券管理", description = "优惠券相关接口")
@Validated
public class CouponController {

    private final CouponManagementService couponManagementService;
    private final CouponUserService couponUserService;
    private final CouponCalculationService couponCalculationService;
    private final CouponUsageService couponUsageService;

    @GetMapping("/page")
    @Operation(summary = "分页查询优惠券", description = "分页查询优惠券列表")
    @RequireAuth(admin = true)
    public Result<PageResult<CouponVO>> getCouponPage(@Validated CouponQuery query) {
        log.info("分页查询优惠券，查询条件: {}", query);
        PageResult<CouponVO> result = couponManagementService.getCouponPage(query);
        return Result.success(result);
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取优惠券详情", description = "根据优惠券ID获取详细信息")
    @Parameter(name = "id", description = "优惠券ID", required = true)
    public Result<CouponVO> getCouponById(@PathVariable @NotBlank String id) {
        log.info("获取优惠券详情: {}", id);
        CouponVO result = couponManagementService.getCouponById(id);
        return Result.success(result);
    }

    @PostMapping
    @Operation(summary = "创建优惠券", description = "创建新的优惠券")
    @RequireAuth(admin = true)
    @Log(description = "创建优惠券", operationType = OperationTypeEnum.ADD)
    public Result<String> createCoupon(@Validated @RequestBody CouponDTO couponDTO) {
        log.info("创建优惠券: {}", couponDTO.getName());
        String couponId = couponManagementService.createCoupon(couponDTO);
        return Result.success(couponId);
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新优惠券", description = "更新优惠券信息")
    @Parameter(name = "id", description = "优惠券ID", required = true)
    @RequireAuth(admin = true)
    @Log(description = "更新优惠券", operationType = OperationTypeEnum.UPDATE)
    public Result<Boolean> updateCoupon(@PathVariable @NotBlank String id,
                                      @Validated @RequestBody CouponDTO couponDTO) {
        log.info("更新优惠券: {}", id);
        Boolean result = couponManagementService.updateCoupon(id, couponDTO);
        return Result.success(result);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除优惠券", description = "删除优惠券")
    @Parameter(name = "id", description = "优惠券ID", required = true)
    @RequireAuth(admin = true)
    @Log(description = "删除优惠券", operationType = OperationTypeEnum.DELETE)
    public Result<Boolean> deleteCoupon(@PathVariable @NotBlank String id) {
        log.info("删除优惠券: {}", id);
        Boolean result = couponManagementService.deleteCoupon(id);
        return Result.success(result);
    }

    @DeleteMapping("/batch")
    @Operation(summary = "批量删除优惠券", description = "批量删除优惠券")
    @RequireAuth(admin = true)
    @Log(description = "批量删除优惠券", operationType = OperationTypeEnum.DELETE)
    public Result<Boolean> deleteCouponsBatch(@RequestBody @NotEmpty List<String> ids) {
        log.info("批量删除优惠券，数量: {}", ids.size());
        Boolean result = couponManagementService.deleteCouponsBatch(ids);
        return Result.success(result);
    }

    @GetMapping("/available")
    @Operation(summary = "获取可用优惠券", description = "获取用户可用的优惠券列表")
    @RequireAuth
    public Result<List<CouponVO>> getAvailableCoupons(@RequestParam @NotNull BigDecimal orderAmount) {
        String userId = UserContext.requireUserId();
        log.info("用户 {} 获取可用优惠券，订单金额: {}", userId, orderAmount);
        List<CouponVO> result = couponUserService.getAvailableCoupons(userId, orderAmount);
        return Result.success(result);
    }

    @GetMapping("/user")
    @Operation(summary = "获取用户优惠券", description = "获取用户的优惠券列表")
    @RequireAuth
    public Result<List<CouponVO>> getUserCoupons(@RequestParam(required = false) Integer status) {
        String userId = UserContext.requireUserId();
        log.info("用户 {} 获取优惠券列表，状态: {}", userId, status);
        List<CouponVO> result = couponUserService.getUserCoupons(userId, status);
        return Result.success(result);
    }

    @PostMapping("/{id}/receive")
    @Operation(summary = "领取优惠券", description = "用户领取优惠券")
    @Parameter(name = "id", description = "优惠券ID", required = true)
    @RequireAuth
    @Log(description = "领取优惠券", operationType = OperationTypeEnum.ADD)
    public Result<Boolean> receiveCoupon(@PathVariable @NotBlank String id) {
        String userId = UserContext.requireUserId();
        log.info("用户 {} 领取优惠券: {}", userId, id);
        Boolean result = couponUserService.receiveCoupon(id, userId);
        return Result.success(result);
    }

    @GetMapping("/hot")
    @Operation(summary = "获取热门优惠券", description = "获取热门优惠券列表")
    public Result<List<CouponVO>> getHotCoupons(@RequestParam(defaultValue = "10") @Min(1) Integer limit) {
        log.info("获取热门优惠券，限制数量: {}", limit);
        List<CouponVO> result = couponManagementService.getHotCoupons(limit);
        return Result.success(result);
    }

    @PutMapping("/{id}/status")
    @Operation(summary = "更新优惠券状态", description = "启用或禁用优惠券")
    @Parameter(name = "id", description = "优惠券ID", required = true)
    @RequireAuth(admin = true)
    @Log(description = "更新优惠券状态", operationType = OperationTypeEnum.UPDATE)
    public Result<Boolean> updateCouponStatus(@PathVariable @NotBlank String id,
                                            @RequestParam @NotNull Integer status) {
        log.info("更新优惠券状态: {} -> {}", id, status);
        Boolean result = couponManagementService.updateCouponStatus(id, status);
        return Result.success(result);
    }

    @PostMapping("/calculate-discount")
    @Operation(summary = "计算优惠金额", description = "计算指定优惠券的优惠金额")
    @RequireAuth
    public Result<BigDecimal> calculateDiscountAmount(@RequestParam @NotBlank String userCouponId,
                                                    @RequestParam @NotNull BigDecimal orderAmount) {
        log.info("计算优惠金额: userCouponId={}, orderAmount={}", userCouponId, orderAmount);
        BigDecimal result = couponCalculationService.calculateDiscountAmount(userCouponId, orderAmount);
        return Result.success(result);
    }

    @PostMapping("/check-available")
    @Operation(summary = "检查优惠券可用性", description = "检查优惠券是否可用于指定订单")
    @RequireAuth
    public Result<Boolean> checkCouponAvailable(@RequestParam @NotBlank String userCouponId,
                                              @RequestParam @NotNull BigDecimal orderAmount) {
        log.info("检查优惠券可用性: userCouponId={}, orderAmount={}", userCouponId, orderAmount);
        Boolean result = couponCalculationService.checkCouponAvailable(userCouponId, orderAmount);
        return Result.success(result);
    }

    @GetMapping("/{id}/can-receive")
    @Operation(summary = "检查是否可以领取", description = "检查用户是否可以领取指定优惠券")
    @RequireAuth
    public Result<Boolean> canReceiveCoupon(@PathVariable @NotBlank String id) {
        String userId = UserContext.requireUserId();
        log.info("检查用户 {} 是否可以领取优惠券: {}", userId, id);
        Boolean result = couponUserService.canReceiveCoupon(id, userId);
        return Result.success(result);
    }
}
